#ifndef MYSQLCONN_H
#define MYSQLCONN_H

#include <mysql/mysql.h>
#include <string>


class MysqlConn {
public:
    MysqlConn() {
        _conn = mysql_init(nullptr);
        mysql_set_character_set(_conn, "utf8");
    }

    ~MysqlConn() {
        if (_conn != nullptr) mysql_close(_conn);
        freeResult();
    }

    bool connect(std::string user, 
                 std::string passwd, 
                 std::string dbName,
                 std::string ip,
                 unsigned short port=3306) 
    {
        MYSQL* ptr = mysql_real_connect(_conn, ip.c_str(), user.c_str(), passwd.c_str(), dbName.c_str(), port, nullptr, 0);
        return ptr != nullptr;
    }


    bool update(std::string sql) {
        if (mysql_query(_conn, sql.c_str())) {
            return false;
        }
        return true;
    }


    bool query(std::string sql) {
        freeResult();
        if (mysql_query(_conn, sql.c_str())) {
            return false;
        }
        _result = mysql_store_result(_conn);
        return true;
    }


    bool next() {
        if (_result == nullptr) {
            return false;
        }

        _row = mysql_fetch_row(_result);
        return true;
    }

    std::string value(int index) {
        int rowCount = mysql_num_fields(_result);
        if (index >= rowCount || index < 0) {
            return std::string();
        }
        char *val = _row[index];
        unsigned long length = mysql_fetch_lengths(_result)[index];
        return std::string(val, length);
    }


    bool transaction() {
        return mysql_autocommit(_conn, false);
    }

    bool commit() {
        return mysql_commit(_conn);
    }

    bool rollback() {
        return mysql_rollback(_conn);
    }



private:
    void freeResult(){
        if (_result) {
            mysql_free_result(_result);
        }
    }
    MYSQL* _conn = nullptr;
    MYSQL_RES* _result = nullptr;
    MYSQL_ROW _row = nullptr;
};



#endif